use crate::cluster::{ManagedNode, NodeStatus};
use crate::config::ApiConfig;
use crate::events::EventSystem;
use crate::health::HealthChecker;
use crate::metrics::MetricsCollector;
use crate::raft::RaftManager;
use crate::raft_network::{self, RaftNetworkState, RaftRpcService};
use crate::Error; // Do not use crate::Result alias here (expects single type param)

use axum::{
    extract::{Path, Query, State},
    http::StatusCode,
    response::Json,
    routing::{get, post},
    Router,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tower::ServiceBuilder;
use tower_http::{cors::CorsLayer, limit::RequestBodyLimitLayer, trace::TraceLayer};
use tracing::{error, info};

/// API server for handling HTTP requests
pub struct ApiServer {
    config: ApiConfig,
    app: Router,
    shutdown_tx: Arc<tokio::sync::RwLock<Option<tokio::sync::oneshot::Sender<()>>>>,
}

/// Application state shared across handlers
#[derive(Clone)]
pub struct AppState {
    pub raft_manager: Arc<RaftManager>,
    pub health_checker: Arc<HealthChecker>,
    pub event_system: Arc<EventSystem>,
    pub metrics_collector: Arc<MetricsCollector>,
}

impl ApiServer {
    /// 创建 API Server，构建路由与共享状态
    pub async fn new(
        config: &ApiConfig,
        raft_manager: Arc<RaftManager>,
        health_checker: Arc<HealthChecker>,
        event_system: Arc<EventSystem>,
        metrics_collector: Arc<MetricsCollector>,
    ) -> crate::Result<Self> {
        info!("Initializing API server");

        let state = AppState {
            raft_manager,
            health_checker,
            event_system,
            metrics_collector,
        };

        let app = create_app(state, config).await?;

    Ok(Self { config: config.clone(), app, shutdown_tx: Arc::new(tokio::sync::RwLock::new(None)) })
    }

    /// 启动 HTTP 服务（异步，带优雅关闭）
    pub async fn start(&mut self) -> crate::Result<()> {
        info!("Starting API server on {}", self.config.bind_addr);

        let listener = tokio::net::TcpListener::bind(&self.config.bind_addr)
            .await
            .map_err(|e| Error::api(format!("Failed to bind to address: {}", e)))?;

    let (tx, rx) = tokio::sync::oneshot::channel();
    *self.shutdown_tx.write().await = Some(tx);

        let app = self.app.clone();
        tokio::spawn(async move {
            axum::serve(listener, app)
                .with_graceful_shutdown(async {
                    rx.await.ok();
                    info!("API server shutting down gracefully");
                })
                .await
                .map_err(|e| error!("API server error: {}", e))
                .ok();
        });

        Ok(())
    }

    /// 关闭 HTTP 服务（oneshot 触发）
    pub async fn shutdown(&self) -> crate::Result<()> {
        info!("Shutting down API server");
        if let Some(tx) = self.shutdown_tx.write().await.take() { let _ = tx.send(()); }

        Ok(())
    }
}

/// 构建 Axum 应用，注册所有 REST 路由与中间件（CORS / Trace / 请求体限制）
async fn create_app(state: AppState, config: &ApiConfig) -> crate::Result<Router> {
    // Capture values needed after state is moved into api_routes
    let node_id = state.raft_manager.node_id();
    let api_routes = Router::new()
        // Cluster management
        .route("/cluster/status", get(get_cluster_status))
        .route("/cluster/metrics", get(get_cluster_metrics))
        // Node management
        .route("/nodes", get(list_nodes).post(create_node))
        .route(
            "/nodes/:node_id",
            get(get_node).put(update_node).delete(delete_node),
        )
        .route("/nodes/:node_id/health", get(get_node_health))
        .route("/nodes/:node_id/health/check", post(trigger_health_check))
        // Configuration
        .route("/config", get(get_config).put(update_config))
        // Events
        .route("/events", get(list_events))
        .route("/events/stream", get(stream_events))
        // Failover
        .route("/failover", post(trigger_failover))
        .route("/failover/history", get(get_failover_history))
        .with_state(state);

    // Raft network RPC (mounted at /raft)
    let raft_state = RaftNetworkState { service: std::sync::Arc::new(RaftRpcService::new(node_id)) };
    let raft_router = raft_network::router(raft_state);

    let app = Router::new()
        .nest("/api/v1", api_routes)
        .nest("/raft", raft_router)
        .layer(
            ServiceBuilder::new()
                .layer(TraceLayer::new_for_http())
                .layer(RequestBodyLimitLayer::new(1024 * 1024)) // 1MB limit
                .layer(if config.cors.enabled {
                    CorsLayer::permissive()
                } else {
                    CorsLayer::new()
                }),
        );

    Ok(app)
}

// API Request/Response types
#[derive(Debug, Serialize, Deserialize)]
pub struct ClusterStatusResponse {
    pub cluster_id: String,
    pub leader: Option<NodeInfo>,
    pub members: Vec<NodeInfo>,
    pub metrics: serde_json::Value,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct NodeInfo {
    pub node_id: u64,
    pub address: String,
    pub role: String,
    pub status: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CreateNodeRequest {
    pub id: String,
    pub address: String,
    pub tags: HashMap<String, String>,
    pub config: Option<serde_json::Value>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct UpdateNodeRequest {
    pub status: Option<String>,
    pub tags: Option<HashMap<String, String>>,
    pub config: Option<serde_json::Value>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ListNodesQuery {
    pub status: Option<String>,
    pub region: Option<String>,
    pub limit: Option<usize>,
    pub offset: Option<usize>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct EventQuery {
    pub event_type: Option<String>,
    pub node_id: Option<String>,
    pub since: Option<String>,
    pub limit: Option<usize>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ApiError {
    pub error: ErrorDetails,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ErrorDetails {
    pub code: String,
    pub message: String,
    pub details: Option<serde_json::Value>,
}

// API Handlers

/// 获取集群状态（占位实现）
type ApiResult<T> = std::result::Result<T, StatusCode>;

async fn get_cluster_status(
    State(state): State<AppState>,
) -> ApiResult<Json<ClusterStatusResponse>> {
    let cluster_state = state
        .raft_manager
        .get_metrics()
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    let response = ClusterStatusResponse {
        cluster_id: "default-cluster".to_string(),
        leader: None,        // Extract from cluster_state
        members: Vec::new(), // Extract from cluster_state
        metrics: cluster_state,
    };

    Ok(Json(response))
}

/// 获取集群 Raft Metrics 原始数据
async fn get_cluster_metrics(
    State(state): State<AppState>,
) -> ApiResult<Json<serde_json::Value>> {
    let metrics = state
        .raft_manager
        .get_metrics()
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(metrics))
}

/// 列出受管节点（占位）
async fn list_nodes(
    Query(_query): Query<ListNodesQuery>,
    State(state): State<AppState>,
) -> ApiResult<Json<Vec<ManagedNode>>> {
    let nodes = state.raft_manager.list_managed_nodes().await;
    Ok(Json(nodes))
}

/// 创建受管节点（写入 Raft 状态机）
async fn create_node(
    State(state): State<AppState>,
    Json(req): Json<CreateNodeRequest>,
) -> ApiResult<Json<ManagedNode>> {
    let now = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .unwrap_or_default()
        .as_secs();
    let node = ManagedNode {
        id: req.id,
        address: req.address,
        tags: req.tags,
        status: NodeStatus::Unknown,
        last_seen: now,
        health_checks: Vec::new(),
    };

    // Add node through Raft
    state
        .raft_manager
        .add_managed_node(node.clone())
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(node))
}

/// 获取节点详情（未实现）
async fn get_node(
    Path(_node_id): Path<String>,
    State(_state): State<AppState>,
) -> ApiResult<Json<ManagedNode>> {
    // Implementation would query the cluster state for the specific node
    Err(StatusCode::NOT_FOUND)
}

/// 更新节点信息（未实现）
async fn update_node(
    Path(_node_id): Path<String>,
    State(_state): State<AppState>,
    Json(_req): Json<UpdateNodeRequest>,
) -> ApiResult<Json<ManagedNode>> {
    // Implementation would update the node through Raft
    Err(StatusCode::NOT_IMPLEMENTED)
}

/// 删除节点（写入 Raft）
async fn delete_node(
    Path(node_id): Path<String>,
    State(state): State<AppState>,
) -> ApiResult<StatusCode> {
    state
        .raft_manager
        .remove_managed_node(&node_id)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(StatusCode::NO_CONTENT)
}

/// 获取节点健康信息
async fn get_node_health(
    Path(node_id): Path<String>,
    State(state): State<AppState>,
) -> ApiResult<Json<serde_json::Value>> {
    let health = state
        .health_checker
        .get_node_health(&node_id)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(serde_json::to_value(health).unwrap()))
}

/// 触发节点立即健康检查
async fn trigger_health_check(
    Path(node_id): Path<String>,
    State(state): State<AppState>,
) -> ApiResult<StatusCode> {
    state
        .health_checker
        .trigger_check(&node_id)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(StatusCode::ACCEPTED)
}

/// 获取系统配置（占位）
async fn get_config(State(_state): State<AppState>) -> ApiResult<Json<serde_json::Value>> {
    // Return current configuration
    Ok(Json(serde_json::Value::Null))
}

/// 更新系统配置（占位，未来写入 Raft）
async fn update_config(
    State(_state): State<AppState>,
    Json(_config): Json<serde_json::Value>,
) -> ApiResult<StatusCode> {
    // Update configuration through Raft
    Ok(StatusCode::OK)
}

/// 查询事件列表
async fn list_events(
    Query(query): Query<EventQuery>,
    State(state): State<AppState>,
) -> ApiResult<Json<Vec<serde_json::Value>>> {
    let events = state
        .event_system
        .get_events(
            query.event_type,
            query.node_id,
            query.since,
            query.limit.unwrap_or(100),
        )
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(events))
}

/// 事件 WebSocket 流 (占位)
async fn stream_events(
    State(state): State<AppState>,
    ws: axum::extract::WebSocketUpgrade,
) -> axum::response::Response {
    ws.on_upgrade(|socket| handle_websocket(socket, state))
}

/// WebSocket 连接处理（占位）
async fn handle_websocket(_socket: axum::extract::ws::WebSocket, _state: AppState) {
    // Implementation for WebSocket event streaming
    info!("WebSocket connection established for event streaming");
}

/// 触发故障转移（占位）
async fn trigger_failover(
    State(_state): State<AppState>,
    Json(_req): Json<serde_json::Value>,
) -> ApiResult<StatusCode> {
    // Implementation for triggering failover
    Ok(StatusCode::ACCEPTED)
}

/// 获取故障转移历史（占位）
async fn get_failover_history(
    State(_state): State<AppState>,
) -> ApiResult<Json<Vec<serde_json::Value>>> {
    // Implementation for getting failover history
    Ok(Json(Vec::new()))
}

impl From<Error> for StatusCode {
    fn from(err: Error) -> Self {
        match err {
            Error::NodeNotFound(_) => StatusCode::NOT_FOUND,
            Error::Auth(_) => StatusCode::UNAUTHORIZED,
            Error::RateLimit => StatusCode::TOO_MANY_REQUESTS,
            Error::InvalidRequest(_) => StatusCode::BAD_REQUEST,
            Error::Timeout(_) => StatusCode::REQUEST_TIMEOUT,
            _ => StatusCode::INTERNAL_SERVER_ERROR,
        }
    }
}
